/*****************************************************************************/
/*  gftp.h - include file for the whole ftp program                          */
/*  Copyright (C) 1998-2003 Brian Masney <masneyb@gftp.org>                  */
/*                                                                           */
/*  This program is free software; you can redistribute it and/or modify     */
/*  it under the terms of the GNU General Public License as published by     */
/*  the Free Software Foundation; either version 2 of the License, or        */
/*  (at your option) any later version.                                      */
/*                                                                           */
/*  This program is distributed in the hope that it will be useful,          */
/*  but WITHOUT ANY WARRANTY; without even the implied warranty of           */
/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            */
/*  GNU General Public License for more details.                             */
/*                                                                           */
/*  You should have received a copy of the GNU General Public License        */
/*  along with this program; if not, write to the Free Software              */
/*  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                */
/*****************************************************************************/

/* $Id: gftp.h 934 2007-06-14 02:06:41Z masneyb $ */

#ifndef __GFTP_H
#define __GFTP_H

#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif


#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

/* *BSD include 64bit off_t but _LARGEFILE_SOURCE is not defined. */
#if defined (SIZEOF_OFF_T) && SIZEOF_OFF_T > 4 && !defined (_LARGEFILE_SOURCE)
#define _LARGEFILE_SOURCE 1
#endif

#if defined (_LARGEFILE_SOURCE) && !defined (_LARGEFILE64_SOURCE)
#define _LARGEFILE64_SOURCE 1
#endif

#define _LARGEFILE64_SOURCE 1
#define _FILE_OFFSET_BITS 64

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/time.h>
#ifndef TIOCGWINSZ
#include <sys/ioctl.h>
#endif
#include <sys/wait.h>
#include <sys/utsname.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <glib.h>
#include <limits.h>
#include <netdb.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <ctype.h>
#include <time.h>
#include <utime.h>
#include <signal.h>
#include <termios.h>
#include <pwd.h>
#include <setjmp.h>
#include <dirent.h>
#include <grp.h>
#include <math.h>

#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif

#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif

#ifdef HAVE_STRING_H
#include <string.h>
#else
#include <strings.h>
#endif

#ifdef USE_SSL
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/rand.h>
#include <openssl/ssl.h>
#include <openssl/x509v3.h>
#endif

#ifdef ENABLE_NLS
#include <libintl.h>
#include <locale.h>
#define _(String) gettext (String)
#else 
#define _(String) String
#endif
#define N_(String) String

#ifndef AF_LOCAL
#define AF_LOCAL AF_UNIX
#endif

#ifdef HAVE_GETADDRINFO
#define HAVE_IPV6
#define GFTP_GET_AI_FAMILY(request) ((request) != NULL && (request)->hostp != NULL ? (request)->hostp->ai_family : -1)
#else
#define GFTP_GET_AI_FAMILY(request) AF_INET
#endif

/* Solaris needs this included for major()/minor() */
#ifdef HAVE_SYS_MKDEV_H
#include <sys/mkdev.h>
#endif

/* We need the major() and minor() macros in the user interface. If they aren't
   defined by the system, we'll just define them here. */
#ifndef major
#warning major macro was not defined by the system. Defining one that is probably wrong for your system
#define major(dev) (((dev) >> 8) & 0xff)
#endif

#ifndef minor
#warning minor macro was not defined by the system. Defining one that is probably wrong for your system
#define minor(dev) ((dev) & 0xff)
#endif


#ifdef __GNUC__
# define GFTP_LOG_FUNCTION_ATTRIBUTES __attribute__((format(printf, 3, 4)))
#else
# define GFTP_LOG_FUNCTION_ATTRIBUTES
#endif

#if defined (_LARGEFILE64_SOURCE)
#define GFTP_OFF_T_HEX_PRINTF_MOD   "%llx" 
#define GFTP_OFF_T_INTL_PRINTF_MOD  "%'lld"
#define GFTP_OFF_T_PRINTF_MOD       "%lld"
#define GFTP_OFF_T_11PRINTF_MOD     "%11lld"
#define gftp_parse_file_size(str)   strtoll (str, NULL, 10)
#define GFTP_OFF_T_PRINTF_CONVERSION    long
#else
#define GFTP_OFF_T_HEX_PRINTF_MOD   "%lx"
#define GFTP_OFF_T_INTL_PRINTF_MOD  "%'ld"
#define GFTP_OFF_T_PRINTF_MOD       "%ld"
#define GFTP_OFF_T_11PRINTF_MOD     "%11ld"
#define gftp_parse_file_size(str)   strtol (str, NULL, 10)
#define GFTP_OFF_T_PRINTF_CONVERSION    off_t
#endif

/* Server types (used by FTP protocol from SYST command) */
#define GFTP_DIRTYPE_UNIX   1
#define GFTP_DIRTYPE_EPLF   2
#define GFTP_DIRTYPE_CRAY   3   
#define GFTP_DIRTYPE_NOVELL 4   
#define GFTP_DIRTYPE_DOS    5   
#define GFTP_DIRTYPE_VMS    6   
#define GFTP_DIRTYPE_OTHER  7
#define GFTP_DIRTYPE_MVS    8

/* Error types */
#define GFTP_ERETRYABLE     -1      /* Temporary failure. The GUI
                                       should wait briefly */
#define GFTP_EFATAL     -2          /* Fatal error */
#define GFTP_ERETRYABLE_NO_WAIT -3  /* Temporary failure. The GUI should 
                                       not wait and should reconnect */
#define GFTP_ENOTRANS       -4      /* Custom error. This is returned 
                                       when a FXP transfer is requested */
#define GFTP_ETIMEDOUT      -5      /* Connected timed out */

/* Some general settings */
#define BASE_CONF_DIR       "~/.gftp"
#define CONFIG_FILE     BASE_CONF_DIR "/gftprc"
#define CONFIG_FILE2        BASE_CONF_DIR "/gftprc2"
#define BOOKMARKS_FILE      BASE_CONF_DIR "/bookmarks"
#define LOG_FILE        BASE_CONF_DIR "/gftp.log"
#define MAX_HIST_LEN        10
#define GFTP_URL_USAGE      "[[protocol://][user[:pass]@]site[:port][/directory]]"

typedef enum gftp_logging_level_tag 
{
  gftp_logging_send,
  gftp_logging_recv,
  gftp_logging_error,
  gftp_logging_misc,
  gftp_logging_misc_nolog   /* Log to the screen, but don't log to disk */
} gftp_logging_level;






typedef struct gftp_proxy_hosts_tag 
{
  /* FIXME - add IPV6 stuff here */

  gint32 ipv4_network_address, 
         ipv4_netmask;
  char *domain;
} gftp_proxy_hosts;


#include "gftp-file.h"
#include "gftp-config.h"
#include "request.h"
#include "transfer.h"
#include "gftpio.h"


typedef struct gftp_log_tag
{
  char *msg;
  gftp_logging_level type;
} gftp_log;


typedef struct supported_gftp_protocols_tag 
{
    char *name;         /* Description of protocol */
    int (*init) (gftp_request * request); /* Init function */
    void (*register_options) (void);      /* Protocol options */
    char *url_prefix;           /* URL Prefix */
    unsigned int default_port;  /* Default port */
    unsigned int shown : 1,     /* Whether this protocol is 
                                   shown or not to the user in 
                                   the protocol dropdown box */
              use_threads : 1;  /* Whether or not operations in
                                   this protocol should use threads */
} supported_gftp_protocols;




#define GFTP_FTP_NUM       0
#define GFTP_LOCAL_NUM     1
#define GFTP_SSHV2_NUM     2

/* Global config options. These are defined in options.h */

extern FILE * gftp_logfd;
extern GList *gftp_file_transfer_logs;
extern supported_gftp_protocols gftp_protocols[];
extern char gftp_version[];
extern int gftp_configuration_changed;

extern gftp_config_item gftp_global_config_items [];



/* cache.c */
void gftp_generate_cache_description    (gftp_request *request, 
                                         char *description,
                                         size_t len,
                                         int ignore_directory);

int gftp_new_cache_entry        (gftp_request *request);

int gftp_find_cache_entry       (gftp_request *request);

void gftp_clear_cache_files         (void);

void gftp_delete_cache_entry        (gftp_request *request,
                                     char *descr,
                                     int   ignore_directory);



/* misc.c */
int copyfile (char *source, char *dest);
char* insert_commas         (off_t number, char *dest_str, size_t dest_len);

char* alltrim               (char *str);

char* gftp_expand_path      (const char *src);

guint uint_hash_function (gconstpointer key);

gint uint_hash_compare (gconstpointer path1, gconstpointer path2);

int compare_request             (gftp_request *request1, 
                                 gftp_request *request2, 
                                 int compare_dirs);



gftp_request* gftp_copy_request    (gftp_request *req);

GList* gftp_sort_filelist      (GList *filelist, 
                                int column, 
                                int asds);

char*  gftp_gen_ls_string       (gftp_request * request,
                                 gftp_file * fle, 
                                 char *file_prefixstr, 
                                 char *file_suffixstr);

char*  base64_encode            (char *str);


void   gftp_shutdown            (void);


char*  gftp_build_path         (gftp_request *request,
                                const char *first_element,
                                ...);


char* gftp_scramble_password       (const char *password);

char* gftp_descramble_password     (const char *password);



/* mkstemps.c */
int mkstemps                (char *template, int suffix_len);

/* protocols.c */

int  rfc959_init                (gftp_request *request);

void rfc959_register_module     (void);


int ftps_init                   (gftp_request *request);

void ftps_register_module       (void);

int rfc2068_init                (gftp_request *request);

void rfc2068_register_module    (void);

int https_init              ( gftp_request * request );

void https_register_module      ( void );

int local_init              ( gftp_request * request );

void local_register_module      ( void );

int sshv2_init              ( gftp_request * request );

void sshv2_register_module      ( void );

void ssl_register_module        ( void );



int fsp_init                ( gftp_request * request );

void fsp_register_module        ( void );



void gftp_copy_param_options        ( gftp_request * dest_request,
                      gftp_request * src_request );



char * gftp_string_to_utf8  ( gftp_request * request, 
                      const char *str,
                      size_t *dest_len );

char * gftp_string_from_utf8    ( gftp_request * request, 
                      int force_local,
                      const char *str,
                      size_t *dest_len );

char * gftp_filename_to_utf8    ( gftp_request * request, 
                      const char *str,
                      size_t *dest_len );

char * gftp_filename_from_utf8 ( gftp_request * request, 
                      const char *str,
                      size_t *dest_len );

int gftp_parse_bookmark         ( gftp_request * request, 
                      gftp_request * local_request,
                      const char * bookmark,
                      int *refresh_local );

void gftp_calc_kbs          ( gftp_transfer * tdata, 
                      ssize_t num_read );

time_t parse_time           ( char *str,
                      char **endpos );

int gftp_parse_ls           ( gftp_request * request,
                      const char *lsoutput, 
                      gftp_file *fle,
                      int fd );

int gftp_get_all_subdirs        (gftp_transfer * transfer);

int gftp_connect_server         ( gftp_request * request, 
                      char *service,
                      char *proxy_hostname,
                      unsigned int proxy_port );

#if !defined (HAVE_GETADDRINFO) || !defined (HAVE_GAI_STRERROR)

struct hostent *r_gethostbyname     ( const char *name, 
                      struct hostent *result_buf, 
                      int *h_errnop );

#endif

struct servent *r_getservbyname     ( const char *name, 
                      const char *proto,
                      /*@out@*/ struct servent *result_buf, 
                      int *h_errnop );

int gftp_set_config_options         ( gftp_request * request );

void print_file_list            ( GList * list );


void gftp_calc_kbs          ( gftp_transfer * tdata, 
                      ssize_t num_read );

int gftp_get_transfer_status        ( gftp_transfer * tdata, 
                      ssize_t num_read );



unsigned int gftp_protocol_default_port ( gftp_request * request );

/* pty.c */
char * gftp_get_pty_impl        ( void );

pid_t gftp_exec             ( gftp_request * request,
                      int *fdm,
                      int *ptymfd,
                      char **args );

char *gftp_convert_attributes_from_mode_t ( mode_t mode );

mode_t gftp_convert_attributes_to_mode_t ( char *attribs );


#ifdef USE_SSL
/* sslcommon.c */
int gftp_ssl_startup            ( gftp_request * request );

int gftp_ssl_session_setup      ( gftp_request * request );

void gftp_ssl_free          ( gftp_request * request );

ssize_t gftp_ssl_read           ( gftp_request * request, 
                      void *ptr, 
                      size_t size, 
                      int fd );

ssize_t gftp_ssl_write          ( gftp_request * request, 
                      const char *ptr, 
                      size_t size, 
                      int fd );
#endif /* USE_SSL */



#endif

